package com.glepoch.springbootsecuritymybatis.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.glepoch.springbootsecuritymybatis.bean.User;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        UsernamePasswordAuthenticationToken authRequest = null;
        try {
            String username = this.obtainUsername(request);
            String password = this.obtainPassword(request);
            String loginuuid = request.getParameter("loginuuid");
            if (StringUtils.isEmpty(username)) {
                username = (String) request.getAttribute(SPRING_SECURITY_FORM_USERNAME_KEY);
                password = (String) request.getAttribute(SPRING_SECURITY_FORM_PASSWORD_KEY);
                if (StringUtils.isEmpty(loginuuid)) {
                    loginuuid = (String) request.getAttribute("loginuuid");
                }
                if (StringUtils.isEmpty(username)) {
                    Map<String, Object> loginInfo = new ObjectMapper().readValue(request.getInputStream(), Map.class);
                    username = (String) loginInfo.get(SPRING_SECURITY_FORM_USERNAME_KEY);
                    password = (String) loginInfo.get(SPRING_SECURITY_FORM_PASSWORD_KEY);
                    if (StringUtils.isEmpty(loginuuid)) {
                        loginuuid = (String) loginInfo.get("loginuuid");
                    }
                }
            }
            username = username.trim();
            authRequest = new UsernamePasswordAuthenticationToken(
                    username, password);
        } catch (Exception e) {
            e.printStackTrace();
            authRequest = new UsernamePasswordAuthenticationToken(
                    "", "");
        } finally {
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        Object principal = authResult.getPrincipal();
        Long userId = null;
        if (principal instanceof User) {
            userId = ((User) principal).getId();
        }
        SecurityContextHolder.getContext().setAuthentication(authResult);
        response.sendRedirect("/login/toIndex?userId=" + userId);
        //chain.doFilter(request, response);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        request.setAttribute("loginMsg", failed.getMessage());
        request.getRequestDispatcher("/").forward(request, response);
    }
}